<?php
namespace Common\Controller;

use Demo\Model\TokenModel;
use Think\Controller;
use Common\Model\LogModel as Log;
use Common\Model\UserModel as User;
use Common\Model\OpenIdModel as OpenId;
use Common\Model\ConfigModel as Config;

/**
 * 微信自动回复基础接口
 *
 * @author codebean
 *
 */
class ControllerBaseWeixin extends Controller
{

    private $textTpl = "<xml>
							<ToUserName><![CDATA[%s]]></ToUserName>
							<FromUserName><![CDATA[%s]]></FromUserName>
							<CreateTime>%s</CreateTime>
							<MsgType><![CDATA[%s]]></MsgType>
							<Content><![CDATA[%s]]></Content>
							</xml>";

    private $picTpl = "<xml>
							<ToUserName><![CDATA[%s]]></ToUserName>
							<FromUserName><![CDATA[%s]]></FromUserName>
							<CreateTime>%s</CreateTime>
							<MsgType><![CDATA[news]]></MsgType>
							<ArticleCount>%s</ArticleCount>
							<Articles>
							%s
							</Articles>
							</xml>";

    protected $fromUsername;

    protected $openid;

    protected $toUsername;

    protected $keyword;

    protected $msgType;

    protected $event;

    protected $timestamp;

    protected $nonce;

    protected $userInfo;

    protected $uid;

    public function response()
    {
        // 如果通过浏览器直接访问，输出这个，以便验证当前加载的微信号，配置文件
        if (! $this->checkSignature())
        {
            echo "hi , i'm from wechat id:" . C('WX_HAO') . " , config file : " . APP_STATUS;
            die();
        }

        $echoStr = isset($_GET["echostr"]) ? $_GET["echostr"] : "";
        if ($echoStr)
        {
            echo $echoStr;
            exit();
        }

        // get post data, May be due to the different environments
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

        // extract post data
        if (! empty($postStr))
        {
            $encrypt_type = (isset($_GET['encrypt_type']) && ($_GET['encrypt_type'] == 'aes')) ? "aes" : "raw";
            if($encrypt_type == 'aes'){
                $this->timestamp = $timestamp = $_GET['timestamp'];
                $this->nonce = $nonce = $_GET["nonce"];
                my_log('dsads');
            }else{
                $pc = new \Com\Weixin\WXBizMsgCrypt(C('TOKEN'), C('EncodingAESKey'), C('AppID'));

                $this->timestamp = $timestamp = $_GET['timestamp'];
                $this->nonce = $nonce = $_GET["nonce"];
                $msg_signature = $_GET['msg_signature'];

                $encrypt_type = (isset($_GET['encrypt_type']) && ($_GET['encrypt_type'] == 'aes')) ? "aes" : "raw";

                $decryptMsg = '';
                $errCode = $pc->decryptMsg($msg_signature, $timestamp, $nonce, $postStr, $decryptMsg);
            }


            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);

            $this->fromUsername = $fromUsername = $postObj->FromUserName;
            $this->openid = $openid = "" . $fromUsername;
            $this->toUsername = $toUsername = $postObj->ToUserName;
            $this->keyword = $keyword = trim($postObj->Content);
            $this->msgType = $msgType = trim($postObj->MsgType);
            $this->event = $event = $postObj->Event;


            // 非关注 首次关注则信息类型为event
//            if (!($msgType == "event" && $event == "subscribe"))//如果用户不是新关注
//            {
////                $this->sendTextMsg($this->openid);exit;
//                $u = new User();//创建user对象
//                $open_obj = new OpenId();//创建openid对象
//                $this->uid = $open_obj->openid2Uid($this->openid);//从数据库里面去寻找  看是否用的的opendi存在
//
//                //找不到该用户openid
//                if (empty($this->uid))
//                {
//                    $info = array();
//                    // 非取消关注事件
//                    if (! ($msgType == "event" && $event == "unsubscribe")) //如果也不是取消关注事件
//                    {
//
//                        $flag = 1;
//                        // 获取用户详细信息
//
//                        $info = $u->getWeixinUserDetailInfo($this->openid);
//
//                        if (! $info)
//                        {
//                            $this->log('retry user detail info fail:' . implode(',', $info));
//                            echo "";
//                            return false;
//                        }
//
//                        $config = new Config();
//                        $union_mode = $config->getConfig("UNION_MODE");
//
//                        //UNION_MODE==1模式下，必须需要字段union_id，通常原因是因为公众号没有绑定开放平台
//                        if ($union_mode == 1 && ! $info['union_id'])
//                        {
//                            $this->log('get user union id fail:' . implode(',', $info));
//                            echo "";
//                            return false;
//                        }
//
//                        $info['state'] = 1;
//                        $info['openid'] = $this->openid;
//                        //将用户数据保存到数据库里面
//                        $this->uid = $u->addUser($info);
//
//                        //如果没有插入成功
//                        if (! $this->uid)
//                        {
//                            //写入日志文件
//                            $this->log('file : ' . __FILE__ . ',line:' . __LINE__ . ',readd user fail,openid:' . $this->openid . ". sql:" . $u->getLastSql());
//                            echo "";
//                            return false;
//                        } else
//                        {
//                            //将用户信息读取出来
//                            $where = array();
//                            $where['id'] = $this->uid;
//                            $userInfo = $u->where($where)->find();
//                            if ($userInfo)
//                            {
//                                $this->userInfo = $userInfo;
//                            }
//                        }
//                    } else
//                    {
//
//                        $flag = 3;
//                    }
//                } else
//                {
//                    $flag = 2;
//                    $where = array();
//                    $where['id'] = $this->uid;
//                    $userInfo = $u->where($where)->find();
//                    $this->userInfo = $userInfo;
//                }
//
//                if (! $this->uid && $flag != 3)
//                {
//                    $this->log('can not found uid in Weixin Api,openid: ' . $this->openid . ',flag .' . $flag);
//                    echo "";
//                    return false;
//                }
//            }
//
            if ($msgType == "voice")
            {

                $keyword = trim($postObj->Recognition);
            }

            if ($msgType == "event" && $event == "subscribe")
            {
                // 订阅
                $this->subscribe($postObj);
            } else if ($msgType == "event" && $event == "unsubscribe")
            {
                // 取消订阅
                $this->unsubscribe($postObj);
            } else if ($msgType == "event" && $event == "CLICK")
            {
                // 菜单点击事件
                $this->clickEvent($postObj);
            } else if ($msgType == "event" && $event == "VIEW")
            {
                // 菜单链接事件
                $this->viewEvent($postObj);
            } else if ($msgType == "event" && $event == "SCAN")
            {
                // 扫描事件
                $this->ScanEvent($postObj);
            } else if ($msgType == "text" || $msgType == "voice")
            {
                // 普通类型消息
                $this->answer($postObj);
            } else if ($msgType == "image")
            {
                // 图片类型消息
                $this->image($postObj);
            } else
            {
                // 普通类型消息
                $this->answer($postObj);
            }
        }
    }

    /**
     * [subscribe 订阅]
     *
     * @return [type] [description]
     */
    public function subscribe($obj)
    {
        $token = new TokenModel();
        $token = $token->insertToken();
        $urlarr = array('http://grade1.read-read.cn/index.php?token=','http://grade2.read-read.cn/index.php?token=','http://grade3.read-read.cn/index.php?token=','http://grade3.read-read.cn/index.php?token=');

        $key = mt_rand(0,count($urlarr));
        $url = $urlarr[$key].$token;

        $text = "☀☀成绩查询注意事项☀☀\r\n\r\n";
        $text.= "1 此次查询通过公众号功能进行负载均衡处理,加速查询成绩速度!\r\n\r\n";
        $text.= "2 生成查成绩的链接具有次数(10次)限制\r\n\r\n";
        $text.= "3 获得成绩查询链接方式为 公众号后台回复 查成绩 或者新关注此公众号都会发送带成绩查询的链接\r\n\r\n";
        $text.= "4 还有部分成绩未出,请静候!\r\n\r\n";
        $text.= "5 最后,希望所有同学不挂科🎉🎉🎉!\r\n\r\n";
        $text.="<a href='{$url}'>戳我查成绩!!</a>";
        $this->sendTextMsg($text);
//        $u = new User();
//
//        $open_obj = new OpenId();
//        $this->uid = $open_obj->openid2Uid($this->openid);
//
//        // 新用户
//        if (empty($this->uid))
//        {
//            // 获取用户详细信息
//            $info = $u->getWeixinUserDetailInfo($this->openid);
//            if (! $info)
//            {
//                $this->log('get user detail info fail:' . implode(',', $info));
//                return false;
//            }
//
//            $config = new Config();
//            $union_mode = $config->getConfig("UNION_MODE");
//
//            if ($union_mode == 1 && ! $info['union_id'])
//            {
//                $this->log('get user union id fail:' . implode(',', $info));
//                return false;
//            }
//
//            $info['state'] = 1;
//            $info['openid'] = $this->openid;
//
//            $this->uid = $u->addUser($info);
//
//            if (! $this->uid)
//            {
//                $this->log('add user fail,openid:' . $this->openid . ". sql:" . $u->getLastSql());
//                echo "";
//                return false;
//            }
//
//            // 加粉丝
//            if ($this->uid && ! empty($obj->EventKey))
//            {
//                $code = $obj->EventKey;
//                $code = str_replace('qrscene_', '', $code);
//                $u->addFans($code, $this->uid, 2);
//            }
//        } else
//        {
//            $where = array();
//            $where['id'] = $this->uid;
//
//            $uinfo = $u->where($where)->find();
//
//            $update = array();
//
//            $config = new Config();
//            $union_mode = $config->getConfig("UNION_MODE");
//            if (empty($uinfo['union_id']) && $union_mode == 1)
//            {
//                // 获取用户详细信息
//                $info = $u->getWeixinUserDetailInfo($this->openid);
//                if (! $info || empty($info['union_id']))
//                {
//                    $this->log('union_id is not exsist ! openid:' . $this->openid);
//                    echo "";
//                    return false;
//                }
//                $update = $info;
//            }
//
//            $update['updatetime'] = date('Y-m-d H:i:s');
//            $update['state'] = 1;
//            $u->where($where)->save($update);
//
//            $where = array();
//            $where['openid'] = $this->openid;
//            $update = array();
//            $update['updatetime'] = time();
//            $update['state'] = 1;
//            $open_obj->where($where)->save($update);
//
//            // 加粉丝
//            if ($uinfo['flag'] == 0 && ! empty($obj->EventKey))
//            {
//                $code = $obj->EventKey;
//                $code = str_replace('qrscene_', '', $code);
//                $u->addFans($code, $this->uid, 1);
//            }
//        }
    }

    /**
     * [unsubscribe 取消关注]
     *
     * @return [type] [description]
     */
    public function unsubscribe($obj)
    {
        $u = new User();
        $open_obj = new OpenId();

        $where = array();
        $where['openid'] = $this->openid;

        $update = array();
        $update['updatetime'] = date("Y-m-d H:i:s");

        $u->where($where)->save($update);

        $update = array();
        $update['state'] = 0;
        $update['updatetime'] = date('Y-m-d H:i:s');
        $open_obj->where($where)->save($update);

        echo "";
        die();
    }

    /**
     * [answer 普通文本事件]
     *
     * @return [type] [description]
     */
    public function answer($obj)
    {
        $token =new TokenModel();
        $token = $token->insertToken();
        $urlarr = array('http://grade1.read-read.cn/index.php?token=','http://grade1.read-read.cn/index.php?token=','http://grade1.read-read.cn/index.php?token=','http://grade1.read-read.cn/index.php?token=');

        $url = array_rand($urlarr,1).$token;

        $this->sendTextMsg($url);
    }

    /**
     * [answer 普通图片事件]
     *
     * @return [type] [description]
     */
    public function image($obj)
    {
    }

    /**
     * [clickEvent 自定义菜单点击事件]
     *
     * @param [type] $obj
     *            [description]
     * @return [type] [description]
     */
    public function clickEvent($obj)
    {
    }

    /**
     * 扫描事件
     *
     * @param unknown $obj
     */
    public function ScanEvent($obj)
    {
    }

    /**
     * [viewEvent 自定义菜单URL事件]
     *
     * @param [type] $obj
     *            [description]
     * @return [type] [description]
     */
    public function viewEvent($obj)
    {
        $key = $obj->EventKey;
    }

    /**
     * 发送文本消息
     *
     * @param unknown $contentStr
     */
    public function sendTextMsg($contentStr)
    {
        $msgType = "text";
        $time = time();
        $resultStr = sprintf($this->textTpl, $this->fromUsername, $this->toUsername, $time, $msgType, $contentStr);

        echo $resultStr;
    }

    /**
     * 发送图文消息
     *
     * @param unknown $data
     */
    public function sendPicMsg($data)
    {
        $time = time();

        $item = "";
        foreach ($data as $it)
        {
            $item .= "<item>
			<Title><![CDATA[{$it['title']}]]></Title>
			<Description><![CDATA[{$it['intro']}]]></Description>
			<PicUrl><![CDATA[{$it['img']}]]></PicUrl>
			<Url><![CDATA[{$it['url']}]]></Url>
			</item>";
        }

        $resultStr = sprintf($this->picTpl, $this->fromUsername, $this->toUsername, $time, count($data), $item);

        echo $this->encryptMsg($resultStr);
    }

    /**
     * 发送图片
     *
     * @param unknown $data
     */
    public function sendImage($media_id)
    {
        $time = time();

        $tpl = <<<EOT
<xml>
<ToUserName><![CDATA[{$this->fromUsername}]]></ToUserName>
<FromUserName><![CDATA[{$this->toUsername}]]></FromUserName>
<CreateTime>{$time}</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[{$media_id}]]></MediaId>
</Image>
</xml>
EOT;
        echo $this->encryptMsg($tpl);
    }

    private function checkSignature()
    {
        $signature = isset($_GET["signature"]) ? $_GET["signature"] : "";
        $timestamp = isset($_GET["timestamp"]) ? $_GET["timestamp"] : "";
        $nonce = isset($_GET["nonce"]) ? $_GET["nonce"] : "";

        $token = C('TOKEN');
        $tmpArr = array(
            $token,
            $timestamp,
            $nonce
        );
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if ($tmpStr == $signature)
        {
            return true;
        } else
        {
            return false;
        }
    }

    //解密
    private function encryptMsg($content)
    {
        $pc = new \Com\Weixin\WXBizMsgCrypt(C('TOKEN'), C('EncodingAESKey'), C('AppID'));
        $errCode = $pc->encryptMsg($content, $this->timestamp, $this->nonce, $encryptMsg);
        if ($errCode !== 0)
        {
            $this->log('encryptMsg fail:' . $errCode);

        }

        return $encryptMsg;
    }

    /**
     * 日志记录
     *
     * @param unknown $content
     */
    protected function log($content)
    {
        $logs = new Log();
        $data = array();
        $data['text'] = $content;
        $data['position'] = 'file : ' . __FILE__;
        $logs->add($data);
    }
}
